﻿using System.Collections.Generic;
using System.ComponentModel;

namespace Borg.Framework
{
    public abstract class CheckedListBox : System.Windows.Forms.CheckedListBox
    {
        private readonly ObjectCollection<object, object> _items =
            new ObjectCollection<object, object>();

        protected bool noUpdate;

        protected CheckedListBox()
        {
            _items.Added += ItemsAdded;
            _items.Removed += ItemsRemoved;
            _items.Inserted += ItemsInserted;
            _items.RemovedAt += ItemsRemovedAt;
            _items.ReplacedAt += ItemsReplacedAt;
            _items.Cleared += ItemsCleared;
        }

        private void ItemPropertyChanged(object sender, PropertyChangedEventArgs args)
        {
            if (!args.PropertyName.Equals("Name"))
                return;

            for (var i = 0; i < _items.Count; i++)
            {
                var pair = _items[i];

                if (pair.Value == sender)
                    base.Items[i] = ((IObjectInfo) sender).Name;
            }
        }

        private void ItemsAdded(KeyValuePair<object, object> item)
        {
            if (item.Value is IObjectInfo)
            {
                var info = (IObjectInfo) item.Value;
                base.Items.Add(info.Name);
                RegisterPropertyChanged(item.Value);
            }
            else
                base.Items.Add(item.Value);
        }

        private void ItemsCleared(KeyValuePair<object, object> item)
        {
            base.Items.Clear();
        }

        private void ItemsInserted(int index, KeyValuePair<object, object> item)
        {
            if (item.Value is IObjectInfo)
            {
                var info = (IObjectInfo) item.Value;
                base.Items.Insert(index, info.Name);
                RegisterPropertyChanged(item.Value);
            }
            else
                base.Items.Insert(index, item.Value);
        }

        private void ItemsRemoved(KeyValuePair<object, object> item)
        {
            if (item.Value is IObjectInfo)
            {
                var info = (IObjectInfo) item.Value;
                base.Items.Remove(info.Name);
                UnregisterPropertyChanged(item.Value);
            }
            else
                base.Items.Remove(item.Value);
        }

        private void ItemsRemovedAt(int index, KeyValuePair<object, object> item)
        {
            var flag = index == SelectedIndex;
            base.Items.RemoveAt(index);
            UnregisterPropertyChanged(item.Value);

            if (flag)
                OnSelectedIndexChanged(null);
        }

        private void ItemsReplacedAt(int index, KeyValuePair<object, object> item)
        {
            object obj2 = base.Items.IndexOf(index);
            UnregisterPropertyChanged(obj2);

            if (item.Value is IObjectInfo)
            {
                var info = (IObjectInfo) item.Value;
                base.Items[index] = info.Name;
                RegisterPropertyChanged(info);
            }
            else
                base.Items[index] = item.Value;
        }

        private static void RegisterPropertyChanged(object obj)
        { }

        private static void UnregisterPropertyChanged(object obj)
        { }

        public new ObjectCollection<object, object> Items
        {
            get { return _items; }
        }

        public new KeyValuePair<object, object> SelectedItem
        {
            get { return _items[SelectedIndex]; }
        }
    }
}

